function [forecast]=conditionalForecastSub(reportPos,GG,RR,ZZ,CC,nforc,...
    sT,etaMat,groupStru,transformStru) 
% =========================================================================
% =========================================================================
% conditionalForecastsSub
% 
% Generate model-based forecasts 

% function [forc_mat,yforc]=zb_quickforecast(reportPos,GG,ZZ,CC,nforc,sT,pos_gdpdef,popsTF,in) 
% 
%% 1. Inputs 
% -------------------------------------------------------------------------
% GG,ZZ,CC  :Solution matrices of model 
% NFORC     :Number of Forecasts    
% ST        :Last data state, e.g. ST|T
% etaMAT    :Matrix of future shocks, e.g. ETA(T+1),
% ETA(T+2),.....,ETA(T+nforc). Matrix will *NOT* be padded inside the code 
% fill with zeros outside if needed 
% *groupStru* group Structure with fieds 
% 
% 
% .PARAM_GDPSS:     Constant for GDP Deflator 
%
%% 2. Outputs 
% -------------------------------------------------------------------------
% *Note:* last state is in the first row 
% FORC_SON:     [length(reportPos) NFORC] Matrix of forecasts with all
%               shocks on 
% FORC_SOFF:    [length(reportPos) NFORC] Matrix of forecasts with all
%               shocks off
% FORC_DECOMP   [length(reportPos) NFORC NGROUPS] Decomposes the difference
%               between forecasts on and off across groups, and check these
%               sum. 
% Alejandro Justiniano December 1st 2010 
% =========================================================================
% =========================================================================

%% Check ETAMAT is of right size 
if size(etaMat,1)~=nforc 
    disp('ETAMAT must have as many rows as forecasts') 
end 

if nargin < 10 || isempty(transformStru) 
    flagTransform=false; 
else 
    flagTransform=true; 
end 
    

%% forecast.shocksAllOff: Generate recursive Forecasts with ALL Shocks set to zero 
% This is the unconiditional forecast 
% sT is the jumping State, in deviations from model mean 
% Number of actual forecasts is NFORC
[stforc_Soff]=zb_forecast_loop(GG,RR,ZZ,CC,sT,[],nforc); 
forecast.shocksAllOff=stforc_Soff(:,reportPos);

if flagTransform==true
forecast.shocksAllOff=conditionalForecastTransform(forecast.shocksAllOff,...
    transformStru); 
end

%% forecast.shocksAllOn: Generate recursive Forecasts with ALL Shocks On 
stforc_SOn=zb_forecast_loop(GG,RR,ZZ,CC,sT,etaMat,nforc); 
forecast.shocksAllOn=stforc_SOn(:,reportPos);
if flagTransform==true
forecast.shocksAllOn=conditionalForecastTransform(forecast.shocksAllOn,...
    transformStru); 
end 

forecast.error=forecast.shocksAllOn-forecast.shocksAllOff; 

checkGroups=[]; 
Ngroups=groupStru.Ngroups; 
forecast.perGroup=zeros( [size(forecast.shocksAllOn) Ngroups] ); 
forecast.errorPerGroup=zeros( [size(forecast.shocksAllOn) Ngroups] ); 

%% forecast.shocksGroup
for ii=1:groupStru.Ngroups; 
    fldnm=['p',num2str(ii)]; 
    shockPosition=groupStru.(fldnm); 
    % Fake matrix of Innovations 
    eta_temp=zeros(size(etaMat) ); 
    eta_temp(:,shockPosition)=etaMat(:,shockPosition); 
    % Forecast with only those shocks on 
    st_temp=zb_forecast_loop(GG,RR,ZZ,CC,sT,eta_temp,nforc); 
    
    forecast.perGroup(:,:,ii)=st_temp(:,reportPos); 
    if flagTransform==true
        forecast.perGroup(:,:,ii)=conditionalForecastTransform(forecast.perGroup(:,:,ii),...
            transformStru);
    end    
    % Forecast error Per Group 
    forecast.errorPerGroup(:,:,ii)=forecast.perGroup(:,:,ii)-forecast.shocksAllOff; 
    checkGroups=[checkGroups;shockPosition(:)]; 
end 
if length(unique(checkGroups))~=size(etaMat,2); 
    error('Wrong partition of shocks...check groupStru') 
end 
maxdif=comparemat(squeeze(sum(forecast.errorPerGroup,3)),...
    forecast.error);
if maxdif > 1e-7;
     disp('Conditional Forecasts cannot be decomposed across shock groups');
    error('Conditional Forecasts cannot be decomposed across shock groups');
end 